package com.food.service.impl;

import com.food.mapper.FoodMapper;
import com.food.mapper.UserGoalMapper;
import com.food.mapper.UserProfileMapper;
import com.food.model.Food;
import com.food.model.UserGoal;
import com.food.model.UserProfile;
import com.food.service.FoodRecommendationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class FoodRecommendationServiceImpl implements FoodRecommendationService {

    @Autowired
    private FoodMapper foodMapper;

    @Autowired
    private UserGoalMapper userGoalMapper;

    @Autowired
    private UserProfileMapper userProfileMapper;

    @Override
    public List<Food> getRecommendedFoods(Integer userId) {
        UserGoal userGoal = userGoalMapper.findByUserId(userId);
        UserProfile userProfile = userProfileMapper.findByUserId(userId);

        // 根据用户目标和个人信息计算每日所需营养
        int dailyCalories = calculateDailyCalories(userProfile, userGoal);
        double dailyProtein = calculateDailyProtein(userProfile, userGoal);
        double dailyCarbs = calculateDailyCarbs(userProfile, userGoal);
        double dailyFat = calculateDailyFat(userProfile, userGoal);

        // 获取符合营养需求的食物
        List<Food> allFoods = foodMapper.findAll();
        return allFoods.stream()
                .filter(food -> isNutritionSuitable(food, dailyCalories/3, dailyProtein/3, dailyCarbs/3, dailyFat/3))
                .collect(Collectors.toList());
    }

    @Override
    public List<Food> getRecommendedFoodsByMealType(Integer userId, String mealType) {
        List<Food> recommendedFoods = getRecommendedFoods(userId);
        return recommendedFoods.stream()
                .filter(food -> isSuitableForMealType(food, mealType))
                .collect(Collectors.toList());
    }

    @Override
    public List<Food> getRecommendedFoodsByNutrition(Integer userId) {
        UserProfile profile = userProfileMapper.findByUserId(userId);
        return foodMapper.findByNutritionNeeds(
                calculateDailyCalories(profile, null),
                calculateDailyProtein(profile, null),
                calculateDailyCarbs(profile, null),
                calculateDailyFat(profile, null)
        );
    }

    @Override
    public List<Food> getRecommendedFoodsByUserPreference(Integer userId) {
        // 获取用户偏好的食物类型
        List<String> preferredCategories = foodMapper.findUserPreferredCategories(userId);
        return foodMapper.findByCategories(preferredCategories);
    }

    @Override
    public List<Food> getRecommendedFoodsByUserGoal(Integer userId) {
        UserGoal goal = userGoalMapper.findByUserId(userId);
        if (goal == null) {
            return getRecommendedFoods(userId);
        }

        switch (goal.getGoalType()) {
            case "减肥":
                return foodMapper.findLowCalorieFoods();
            case "增肌":
                return foodMapper.findHighProteinFoods();
            default:
                return foodMapper.findBalancedFoods();
        }
    }

    private int calculateDailyCalories(UserProfile profile, UserGoal goal) {
        // 基础代谢率计算 (BMR)
        double bmr;
        if ("男".equals(profile.getGender())) {
            bmr = 88.362 + (13.397 * profile.getWeight().doubleValue()) 
                + (4.799 * profile.getHeight().doubleValue()) 
                - (5.677 * profile.getAge());
        } else {
            bmr = 447.593 + (9.247 * profile.getWeight().doubleValue()) 
                + (3.098 * profile.getHeight().doubleValue()) 
                - (4.330 * profile.getAge());
        }

        // 活动系数
        double activityFactor = getActivityFactor(profile.getActivityLevel());
        
        // 总热量需求
        double totalCalories = bmr * activityFactor;

        // 根据目标调整热量
        if (goal != null) {
            switch (goal.getGoalType()) {
                case "减肥":
                    totalCalories *= 0.8;
                    break;
                case "增肌":
                    totalCalories *= 1.2;
                    break;
            }
        }

        return (int) totalCalories;
    }

    private double calculateDailyProtein(UserProfile profile, UserGoal goal) {
        double proteinPerKg;
        if (goal != null && "增肌".equals(goal.getGoalType())) {
            proteinPerKg = 2.0;
        } else {
            proteinPerKg = 1.2;
        }
        return profile.getWeight().doubleValue() * proteinPerKg;
    }

    private double calculateDailyCarbs(UserProfile profile, UserGoal goal) {
        double carbsPerKg;
        if (goal != null) {
            switch (goal.getGoalType()) {
                case "减肥":
                    carbsPerKg = 2.0;
                    break;
                case "增肌":
                    carbsPerKg = 6.0;
                    break;
                default:
                    carbsPerKg = 4.0;
            }
        } else {
            carbsPerKg = 4.0;
        }
        return profile.getWeight().doubleValue() * carbsPerKg;
    }

    private double calculateDailyFat(UserProfile profile, UserGoal goal) {
        double fatPerKg;
        if (goal != null && "减肥".equals(goal.getGoalType())) {
            fatPerKg = 0.8;
        } else {
            fatPerKg = 1.0;
        }
        return profile.getWeight().doubleValue() * fatPerKg;
    }

    private double getActivityFactor(String activityLevel) {
        switch (activityLevel) {
            case "低":
                return 1.2;
            case "中":
                return 1.55;
            case "高":
                return 1.725;
            default:
                return 1.2;
        }
    }

    private boolean isNutritionSuitable(Food food, double targetCalories, double targetProtein, 
                                      double targetCarbs, double targetFat) {
        // 允许20%的误差范围
        return isWithinRange(food.getCalories(), targetCalories, 0.2) &&
               isWithinRange(food.getProtein().doubleValue(), targetProtein, 0.2) &&
               isWithinRange(food.getCarbohydrates().doubleValue(), targetCarbs, 0.2) &&
               isWithinRange(food.getFat().doubleValue(), targetFat, 0.2);
    }

    private boolean isWithinRange(double value, double target, double tolerance) {
        double min = target * (1 - tolerance);
        double max = target * (1 + tolerance);
        return value >= min && value <= max;
    }

    private boolean isSuitableForMealType(Food food, String mealType) {
        // 根据食物类别和营养成分判断是否适合某个餐次
        switch (mealType) {
            case "早餐":
                return food.getCategory().contains("谷物") || 
                       food.getCategory().contains("水果") || 
                       food.getCategory().contains("乳制品");
            case "午餐":
            case "晚餐":
                return food.getCategory().contains("肉类") || 
                       food.getCategory().contains("蔬菜") || 
                       food.getCategory().contains("主食");
            case "零食":
                return food.getCategory().contains("零食") || 
                       food.getCategory().contains("水果");
            default:
                return true;
        }
    }
} 